//-------------------------------------------------------------------
//	Copyright (c) 2010-2011  Zhirnov Andrey
//	This file is part of the "UXGEN_ResourceConverter" project.
//	See copyright notice in "Converter.h".
//-------------------------------------------------------------------

#ifndef _RC_TEXTURE_CONVERTER_H
#define _RC_TEXTURE_CONVERTER_H

#include "stdafx.h"


class ITexture;


class CTextureConverter : public ITextureConverter
{
private:
	ITexture		*	_pTex;
	E_TEXTURE_TYPE		_eType;
	
private:
	bool _SaveTexture1D();
	bool _SaveTexture2D();
	bool _SaveTexture3D();

public:
	CTextureConverter();
	~CTextureConverter();

	// ITextureConverter //
	virtual HRESULT CALLBACK GetSupportedFormats(char *pBuffer, uint uCount);

	virtual HRESULT CALLBACK Create(E_TEXTURE_TYPE eType);
	virtual HRESULT CALLBACK Delete();
	virtual HRESULT CALLBACK Load(const char *pFileName);
	virtual HRESULT CALLBACK Save(const char *pFileName);

	virtual HRESULT CALLBACK GetInternalFormatName(uint uFormat, char *pBuffer, uint uCount);
	virtual HRESULT CALLBACK GetColorFormatName(uint uFormat, char *pBuffer, uint uCount);
	virtual HRESULT CALLBACK GetColorTypeName(uint uType, char *pBuffer, uint uCount);
	
	virtual HRESULT CALLBACK GetName(uint uLayer, uint uMipmap, char *pBuffer, uint uCount);

	virtual HRESULT CALLBACK GetFormat(TTextureFormat &sFormat);
	virtual HRESULT CALLBACK SetFormat(const TTextureFormat &sFormat);

	virtual HRESULT CALLBACK GetTexType(E_TEXTURE_TYPE &eType);
	virtual HRESULT CALLBACK GetDimension(TPoint3u &sDim);
	virtual HRESULT CALLBACK GetInfo(char *pBuffer, uint uCount);

	virtual HRESULT CALLBACK LoadMipmap(const char *pFileName, uint uLayer, uint &uMipmapNumb);
	virtual HRESULT CALLBACK LoadLayer(const char *pFileName, uint &uLayer);

	virtual HRESULT CALLBACK RemoveLayer(uint uLayer);
	virtual HRESULT CALLBACK RemoveMipmap(uint uLayer, uint uMipmap);
	virtual HRESULT CALLBACK SwapLayers(uint uFrom, uint uTo);

	// ISubSystem //
	virtual HRESULT CALLBACK GetType(E_SUBSYSTEM_TYPE &eType);
	
	IBASE_IMPLEMENTATION( ITextureConverter )
};



class ITexture
{
public:
	virtual ~ITexture() {}

	virtual HRESULT SetImage(const char *pName) = 0;
	virtual HRESULT AddLayer(const char *pName, uint &uLayer) = 0;
	virtual HRESULT AddMipmap(const char *pName, uint uLayer, uint &uMM) = 0;
	
	virtual HRESULT GetName(uint uLayer, uint uMipmap, char *pBuffer, uint uCount) = 0;
	virtual HRESULT Save(IFilePtr pFile) = 0;

	virtual HRESULT GetFormat(TTextureFormat &sFormat) = 0;
	virtual HRESULT SetFormat(const TTextureFormat &sFormat) = 0;

	virtual HRESULT GetTexType(E_TEXTURE_TYPE &eType) = 0;
	virtual HRESULT GetDimension(TPoint3u &sDim) = 0;

	virtual HRESULT RemoveLayer(uint uLayer) = 0;
	virtual HRESULT RemoveMipmap(uint uLayer, uint uMipmap) = 0;
	virtual HRESULT SwapLayers(uint uFrom, uint uTo) = 0;

	virtual e_tex_format::type GetTexFormat() const = 0;
};


class CTexture1D : public ITexture
{
private:
	struct TImage1DExt
	{
		TImage1D	sImage;
		string		sName;
		///
		TImage1DExt() {}
		TImage1DExt(const TImage1D &img, const char *name): sImage(img), sName(name) {}
	};

private:
	array< TImage1DExt >	_aImages;
	e_tex_format::type		_eFormat;
	e_tex_swizzle::type		_eSwizzle;
	bool					_bMipmaps;
	bool					_bUseCompression;
	bool					_bCompressed;

public:
	CTexture1D();
	~CTexture1D();
	
	virtual HRESULT SetImage(const char *pName);
	virtual HRESULT AddLayer(const char *pName, uint &uLayer);
	virtual HRESULT AddMipmap(const char *pName, uint uLayer, uint &uMM);

	virtual HRESULT GetName(uint uLayer, uint uMipmap, char *pBuffer, uint uCount);
	virtual HRESULT Save(IFilePtr pFile);

	virtual HRESULT GetFormat(TTextureFormat &sFormat);
	virtual HRESULT SetFormat(const TTextureFormat &sFormat);

	virtual HRESULT GetTexType(E_TEXTURE_TYPE &eType);
	virtual HRESULT GetDimension(TPoint3u &sDim);

	virtual HRESULT RemoveLayer(uint uLayer);
	virtual HRESULT RemoveMipmap(uint uLayer, uint uMipmap);
	virtual HRESULT SwapLayers(uint uFrom, uint uTo);

	virtual e_tex_format::type GetTexFormat() const	{ return _eFormat; }
};



class CTexture2D : public ITexture
{
private:
	struct TImage2DExt
	{
		TImage2D	sImage;
		string		sName;
		///
		TImage2DExt() {}
		TImage2DExt(const TImage2D &img, const char *name): sImage(img), sName(name) {}
	};

private:
	array< TImage2DExt >	_aImages;
	e_tex_format::type		_eFormat;
	e_tex_swizzle::type		_eSwizzle;
	bool					_bMipmaps;
	bool					_bUseCompression;
	bool					_bCompressed;

public:
	CTexture2D();
	~CTexture2D();
	
	virtual HRESULT SetImage(const char *pName);
	virtual HRESULT AddLayer(const char *pName, uint &uLayer);
	virtual HRESULT AddMipmap(const char *pName, uint uLayer, uint &uMM);

	virtual HRESULT GetName(uint uLayer, uint uMipmap, char *pBuffer, uint uCount);
	virtual HRESULT Save(IFilePtr pFile);

	virtual HRESULT GetFormat(TTextureFormat &sFormat);
	virtual HRESULT SetFormat(const TTextureFormat &sFormat);

	virtual HRESULT GetTexType(E_TEXTURE_TYPE &eType);
	virtual HRESULT GetDimension(TPoint3u &sDim);

	virtual HRESULT RemoveLayer(uint uLayer);
	virtual HRESULT RemoveMipmap(uint uLayer, uint uMipmap);
	virtual HRESULT SwapLayers(uint uFrom, uint uTo);

	virtual e_tex_format::type GetTexFormat() const	{ return _eFormat; }
};


class CTexture3D : public ITexture
{
private:
	struct TImage3DExt
	{
		TImage3D	sImage;
		string		sName;
		///
		TImage3DExt() {}
		TImage3DExt(const TImage3D &img, const char *name): sImage(img), sName(name) {}
	};

private:
	array< TImage3DExt >	_aImages;
	e_tex_format::type		_eFormat;
	e_tex_swizzle::type		_eSwizzle;
	bool					_bMipmaps;
	bool					_bUseCompression;
	bool					_bCompressed;

public:
	CTexture3D();
	~CTexture3D();
	
	virtual HRESULT SetImage(const char *pName);
	virtual HRESULT AddLayer(const char *pName, uint &uLayer);
	virtual HRESULT AddMipmap(const char *pName, uint uLayer, uint &uMM);

	virtual HRESULT GetName(uint uLayer, uint uMipmap, char *pBuffer, uint uCount);
	virtual HRESULT Save(IFilePtr pFile);

	virtual HRESULT GetFormat(TTextureFormat &sFormat);
	virtual HRESULT SetFormat(const TTextureFormat &sFormat);

	virtual HRESULT GetTexType(E_TEXTURE_TYPE &eType);
	virtual HRESULT GetDimension(TPoint3u &sDim);

	virtual HRESULT RemoveLayer(uint uLayer);
	virtual HRESULT RemoveMipmap(uint uLayer, uint uMipmap);
	virtual HRESULT SwapLayers(uint uFrom, uint uTo);

	virtual e_tex_format::type GetTexFormat() const	{ return _eFormat; }
};


class CTexture2DArr : public ITexture
{
private:
	struct TImage2DExt
	{
		TImage2D	sImage;
		string		sName;
		///
		TImage2DExt() {}
		TImage2DExt(const TImage2D &img, const char *name): sImage(img), sName(name) {}
	};

	struct TImage2DAExt
	{
		array< TImage2DExt >	aImages;	// mipmaps
		///
		TImage2DAExt() {}
		TImage2DAExt(const TImage2D &img, const char *name)
		{
			aImages.PushBack( TImage2DExt( img, name ) );
		}
	};

private:
	array< TImage2DAExt >	_aImages;
	e_tex_format::type		_eFormat;
	e_tex_swizzle::type		_eSwizzle;
	E_TEXTURE_TYPE	const	_eType;
	bool					_bMipmaps;
	bool					_bUseCompression;
	bool					_bCompressed;

public:
	CTexture2DArr(E_TEXTURE_TYPE eType);
	~CTexture2DArr();
	
	virtual HRESULT SetImage(const char *pName);
	virtual HRESULT AddLayer(const char *pName, uint &uLayer);
	virtual HRESULT AddMipmap(const char *pName, uint uLayer, uint &uMM);

	virtual HRESULT GetName(uint uLayer, uint uMipmap, char *pBuffer, uint uCount);
	virtual HRESULT Save(IFilePtr pFile);

	virtual HRESULT GetFormat(TTextureFormat &sFormat);
	virtual HRESULT SetFormat(const TTextureFormat &sFormat);

	virtual HRESULT GetTexType(E_TEXTURE_TYPE &eType);
	virtual HRESULT GetDimension(TPoint3u &sDim);

	virtual HRESULT RemoveLayer(uint uLayer);
	virtual HRESULT RemoveMipmap(uint uLayer, uint uMipmap);
	virtual HRESULT SwapLayers(uint uFrom, uint uTo);

	virtual e_tex_format::type GetTexFormat() const	{ return _eFormat; }
};


#endif	// _RC_TEXTURE_CONVERTER_H